﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DataAccessLayer;
using GlobalObjects;
using System.Collections.Generic;

namespace DataAccessLayerTests
{
    [TestClass]
    public class DeviceEntityTests
    {
        [TestMethod]
        public void addDevice_DAL_valid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            Device device = new Device();
            device.User_id = 1178;
            device.Name = "pejmanDevice";
            device.Location = "London";
            device.Description = "unit test";
            device.Privacy = "private";
            device.Ip = "0.0.0.0";
            device.Longlat = "51.47026338272034, -0.17578125";
            //act
            Device newDevice = deviceEntity.addDevice_DAL(device);
            //assert
            Assert.IsNotNull(newDevice.Id);
            Assert.IsNotNull(newDevice.APIKey);
            Assert.AreEqual(newDevice.User_id, 1135);
            Assert.AreEqual(newDevice.Name, "pejmanDevice");
            Assert.AreEqual(newDevice.Location, "London");
            Assert.AreEqual(newDevice.Description, "unit test");
            Assert.AreEqual(newDevice.Privacy, "private");
            Assert.AreEqual(newDevice.Ip, "0.0.0.0");
            Assert.AreEqual(newDevice.Longlat, "51.47026338272034, -0.17578125");
        }
        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void addDevice_DAL_sameName()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            Device device = new Device();
            device.User_id = 1090;
            device.Name = "mypublic";
            device.Location = "London";
            device.Description = "abc";
            device.Privacy = "puublic";
            //act
            Device newDevice = deviceEntity.addDevice_DAL(device);
            //assert handled by expected exception
        }

        [TestMethod]
        public void nameExist_DAL_exist()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int user_id = 1092;
            string name = "testingDevice";
            //act//
            Boolean result = deviceEntity.nameExist_DAL(user_id, name);
            //assert
            Assert.IsTrue(result);
        }
        [TestMethod]
        public void nameExist_DAL_notExist()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int user_id = 1092;
            string name = "randomName";
            //act//
            Boolean result = deviceEntity.nameExist_DAL(user_id, name);
            //assert
            Assert.IsFalse(result);
        }

        [TestMethod]
        public void getDeviceById_DAL_validPublic()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int user_id = 1090;
            int device_id = 1060;
            //act
            Device device = deviceEntity.getDeviceById_DAL(user_id, device_id);
            // assert
            Assert.AreEqual(device.Name, "MyFirstDevice");
        }

        [TestMethod]
        public void getDeviceById_DAL_validPrivate()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int user_id = 1092;
            int device_id = 1062;
            //act
            Device device = deviceEntity.getDeviceById_DAL(user_id, device_id);
            // assert
            Assert.AreEqual(device.Name, "MySecondDevice");
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void getDeviceById_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int user_id = 1090;
            int device_id = 1062;
            //act
            Device device = deviceEntity.getDeviceById_DAL(user_id, device_id);
            // assert
        }

        [TestMethod]
        public void checkApikeyExist_DAL_exist()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            string key = "bf9e6201-63a6-4422-a2f4-40e27ce468d4";
            //act
            Boolean result = deviceEntity.checkApikeyExist_DAL(key);
            // assert
            Assert.IsTrue(result);
        }

        [TestMethod]
        public void checkApikeyExist_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            string key = "newAPIkey";
            //act
            Boolean result = deviceEntity.checkApikeyExist_DAL(key);
            // assert
            Assert.IsFalse(result);
        }
        [TestMethod]
        public void getDeviceIdByUserId_DAL_validUserId()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int userId = 1093;
            //act
            List<int> result = deviceEntity.getDeviceIdByUserId_DAL(userId);
            // assert
            Assert.AreEqual(result[0], 1061);
        }
        [TestMethod]
        public void getDeviceIdByUserId_DAL_invalidUserId()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int userId = 166;
            //act
            List<int> result = deviceEntity.getDeviceIdByUserId_DAL(userId);
            // assert
            Assert.AreEqual(result.Count, 0);
        }

        [TestMethod]
        public void deleteDeviceById_DAL_validId()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 2110;
            //act
            Boolean result = deviceEntity.deleteDeviceById_DAL(deviceID);
            // assert
            Assert.IsTrue(result);
        }

        [TestMethod]
        public void deleteDeviceById_DAL_invalidId()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 100;
            //act
            Boolean result = deviceEntity.deleteDeviceById_DAL(deviceID);
            // assert
            Assert.IsFalse(result);
        }

        [TestMethod]
        public void APIKeyAndDeviceIdMatch_DAL_match()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 1057;
            string key = "34f783e0-a52a-4fe4-a7b6-9e37a9933bdf";
            //act
            Boolean result = deviceEntity.APIKeyAndDeviceIdMatch_DAL(key, deviceID);
            // assert
            Assert.IsTrue(result);
        }
        [TestMethod]
        public void APIKeyAndDeviceIdMatch_DAL_notmatch()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 1060;
            string key = "97ad10a6";
            //act
            Boolean result = deviceEntity.APIKeyAndDeviceIdMatch_DAL(key, deviceID);
            // assert
            Assert.IsFalse(result);
        }
        [TestMethod]
        public void addIpAddress_DAL_validDeviceId()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 1060;
            string ip = "168.111.11.11";
            //act
            Device result = deviceEntity.addIpAddress_DAL(deviceID, ip);
            // assert
            Assert.AreEqual("168.111.11.11", result.Ip);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void addIpAddress_DAL_invalidDeviceId()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 144;
            string ip = "168.111.11.00";
            //act
            Device result = deviceEntity.addIpAddress_DAL(deviceID, ip);
            // assert
        }
        [TestMethod]
        public void getLongLatById_DAL_valid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 1060;
            //act
            string result = deviceEntity.getLongLatById_DAL(deviceID);
            // assert
            Assert.AreEqual(result, "51.524485462825666, -0.13473272323608398");
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void getLongLatById_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceID = 10600;
            //act
            string result = deviceEntity.getLongLatById_DAL(deviceID);
            // assert

        }

        [TestMethod]
        public void updateDeviceDetails_DAL_valid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            Device updatedDevice = new Device();
            updatedDevice.Id = 1063;
            updatedDevice.User_id = 1092;
            updatedDevice.Name = "device-4";
            updatedDevice.Location = "Tehran";
            updatedDevice.Privacy = "public";
            updatedDevice.Longlat = "51.524485462825666, -0.13473272323608398";
            updatedDevice.Status = true;

            //act
            Device result = deviceEntity.updateDeviceDetails_DAL(updatedDevice);
            //assert
            Assert.AreEqual(result.User_id, 1092);
            Assert.AreEqual(result.Name, "device-4");
            Assert.AreEqual(result.Location, "Tehran");
            Assert.AreEqual(result.Privacy, "public");
            Assert.AreEqual(result.Longlat, "51.524485462825666, -0.13473272323608398");
            Assert.IsTrue(result.Status);
        }

        [TestMethod]
        public void updateDeviceDetails_DAL_valid2()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            Device updatedDevice = new Device();
            updatedDevice.Id = 1063;
            updatedDevice.User_id = 1092;
            updatedDevice.Connection_string = "mongodb://iot:gadg3t33r@ds031108.mongolab.com:31108/iot";
            updatedDevice.Db_name = "iot";
            //act
            Device result = deviceEntity.updateDeviceDetails_DAL(updatedDevice);
            //assert
            Assert.AreEqual(result.User_id, 1092);
            Assert.AreEqual(result.Connection_string, "mongodb://iot:gadg3t33r@ds031108.mongolab.com:31108/iot");
            Assert.AreEqual(result.Db_name, "iot");
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void updateDeviceDetails_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            Device updatedDevice = new Device();
            updatedDevice.Id = 14;
            updatedDevice.User_id = 111;
            //act
            Device result = deviceEntity.updateDeviceDetails_DAL(updatedDevice);
            //assert
        }


        [TestMethod]
        public void isShared_DAL_exist()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 1058;
            int userId = 1092;
            //act
            Boolean result = deviceEntity.isShared_DAL(deviceId, userId);
            //assert
            Assert.IsTrue(result);
        }

        [TestMethod]
        public void isShared_DAL_notExist()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 1058;
            int userId = 200;
            //act
            Boolean result = deviceEntity.isShared_DAL(deviceId, userId);
            //assert
            Assert.IsFalse(result);
        }
        [TestMethod]
        public void getAllAccessibleDevice_DAL_publicAndShared()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int userId = 1092;
            //act
            DeviceDiscovery result = deviceEntity.getAllAccessibleDevice_DAL(userId);
            //assert
            Assert.AreEqual(result.Public.Count, 3);
            Assert.AreEqual(result.Shared.Count, 1);
        }

        [TestMethod]
        public void getAllAccessibleDevice_DAL_publicAndOwn()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int userId = 1092;
            //act
            DeviceDiscovery result = deviceEntity.getAllAccessibleDevice_DAL(userId);
            //assert
            Assert.AreEqual(result.Public.Count, 3);
            Assert.AreEqual(result.Private.Count, 5);
        }

        [TestMethod]
        public void getConnectionStringAndDB_DAL_validDefault()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 1062;
            //act
            Dictionary<string, string> result = deviceEntity.getConnectionStringAndDB_DAL(deviceId);
            //assert
            Assert.AreEqual(result["connectionString"], Mongo.defaultConnectionString);
            Assert.AreEqual(result["databaseName"], Mongo.defaultDatabase);
        }


        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void getConnectionStringAndDB_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 1896;
            //act
            Dictionary<string, string> result = deviceEntity.getConnectionStringAndDB_DAL(deviceId);
            //assert
        }

        [TestMethod]
        public void setConnectionStringAndDB_DAL_valid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 1063;
            //act
            deviceEntity.setConnectionStringAndDB_DAL(deviceId, "default", "default");
            //Assert
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void setConnectionStringAndDB_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 10630;
            //act
            deviceEntity.setConnectionStringAndDB_DAL(deviceId, "default", "default");
            //Assert
        }

        [TestMethod]
        public void idExist_DAL_valid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 1064;
            //act
            Boolean result = deviceEntity.idExist_DAL(deviceId);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod]
        public void idExist_DAL_invalid()
        {
            //arrange
            DeviceEntity deviceEntity = new DeviceEntity();
            int deviceId = 10604;
            //act
            Boolean result = deviceEntity.idExist_DAL(deviceId);
            //Assert
            Assert.IsFalse(result);
        }

    }
}
